package com.jhgsys.internal.peccancy.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jhgsys.internal.base.service.IBaseCautionaryLessonService;
import com.jhgsys.internal.common.annotation.Log;
import com.jhgsys.internal.common.constant.DictCodeConstant;
import com.jhgsys.internal.common.constant.ModuleManagerPermissionConstant;
import com.jhgsys.internal.common.controller.BaseController;
import com.jhgsys.internal.common.entity.FebsConstant;
import com.jhgsys.internal.common.entity.FebsResponse;
import com.jhgsys.internal.common.entity.QueryRequest;
import com.jhgsys.internal.common.exception.FebsException;
import com.jhgsys.internal.common.utils.FebsUtil;
import com.jhgsys.internal.dict.service.IDictService;
import com.jhgsys.internal.peccancy.constant.PeccancyConstant;
import com.jhgsys.internal.peccancy.dto.PeccancyInformationDto;
import com.jhgsys.internal.peccancy.dto.PeccancyInformationQueryDto;
import com.jhgsys.internal.peccancy.entity.PeccancyInformation;
import com.jhgsys.internal.peccancy.entity.PeccancyModuleConfig;
import com.jhgsys.internal.peccancy.service.IPeccancyClauseRuleService;
import com.jhgsys.internal.peccancy.service.IPeccancyInformationService;
import com.jhgsys.internal.peccancy.service.IPeccancyModuleConfigService;
import com.jhgsys.internal.system.entity.User;
import com.jhgsys.internal.workflow.service.IWorkflowApplyService;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Date;

/**
 * 违章登记 Controller
 *
 * @author wanghw
 * @date 2024-08-12 09:46:29
 */
@Slf4j
@Validated
@Controller
public class PeccancyInformationController extends BaseController {

    @Autowired
    private IPeccancyInformationService peccancyInformationService;

    @Autowired
    private IDictService dictService;
    @Autowired
    private IPeccancyClauseRuleService ruleService;

    @Autowired
    private IBaseCautionaryLessonService baseCautionaryLessonService;

    @Autowired
    private IPeccancyModuleConfigService moduleConfigService;

    @Autowired
    private IWorkflowApplyService workflowApplyService;

    @GetMapping(FebsConstant.VIEW_PREFIX + "peccancyInformation")
    @RequiresPermissions("peccancyInformation:view")
    public String peccancyInformationIndex(Model model) {
        model.addAttribute("hasHeadCompanyRole", hasHeadCompanyRole());
        model.addAttribute("tenantList", getTenantList());
        model.addAttribute("currentTenantId", getCurrentTenantId());
        model.addAttribute("peccancyRootCauseList", dictService.findDictByCode(DictCodeConstant.SAFETY_PECCANCY_ROOT_REASON));
        model.addAttribute("jobOperationList", dictService.findDictByCode(DictCodeConstant.SAFETY_JOB_OPERATION));
        model.addAttribute("peccancyTypeList", dictService.findDictByCode(DictCodeConstant.SAFETY_PECCANCY_TYPE));
        return jumpPage("peccancy/peccancyInformation/peccancyInformationList");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "peccancyInformation/add/{tenantId}")
    @RequiresPermissions("peccancyInformation:add")
    public String peccancyInformationAdd(Model model, @PathVariable("tenantId") String tenantId) {
//        model.addAttribute("peccancyNo", peccancyInformationService.createPeccancyNo(tenantId));
        return jumpPage("peccancy/peccancyInformation/peccancyInformationEdit");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "peccancyInformation/update/{id}")
    @RequiresPermissions("peccancyInformation:edit")
    public String peccancyInformationUpdate(Model model, @PathVariable("id") String id) throws JsonProcessingException {
        PeccancyInformationDto dto = peccancyInformationService.findPeccancyInformationDtoById(id);
        model.addAttribute("peccancyInformation", JSON.parse(new ObjectMapper().writeValueAsString(dto)));
        model.addAttribute("disposeFormList", dictService.findDictByCode(DictCodeConstant.SAFETY_PECCANCY_DISPOSE_FORM));
        return jumpPage("peccancy/peccancyInformation/peccancyInformationEdit");

    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "peccancyInformation/detail/{id}")
    @RequiresPermissions("peccancyInformation:view")
    public String peccancyInformationDetail(Model model, @PathVariable("id") String id) throws JsonProcessingException {
        PeccancyInformationDto dto = peccancyInformationService.findPeccancyInformationDtoById(id);
        model.addAttribute("peccancyInformation", JSON.parse(new ObjectMapper().writeValueAsString(dto)));
        model.addAttribute("countYear",peccancyInformationService.countPeccancyByUserId(dto));
        return jumpPage("peccancy/peccancyInformation/peccancyInformationDetail");
    }

    @GetMapping(FebsConstant.VIEW_PREFIX + "peccancyInformation/detailForLesson/{id}/{lessonId}")
    @RequiresPermissions("peccancyInformation:view")
    public String peccancyInformationDetailForLesson(Model model, @PathVariable("id") String id, @PathVariable("lessonId") String lessonId) throws JsonProcessingException {
        PeccancyInformationDto dto = peccancyInformationService.findPeccancyInformationDtoById(id);
        model.addAttribute("peccancyInformation", JSON.parse(new ObjectMapper().writeValueAsString(dto)));
        model.addAttribute("baseCautionaryLesson", baseCautionaryLessonService.findBaseCautionaryLessonById(lessonId));
        return jumpPage("base/baseCautionaryLesson/peccancyInformationDetailForLesson");
    }

    /**
     * 违章信息查询（所有）
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @GetMapping("peccancyInformation")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:view")
    public FebsResponse getAllPeccancyInformations(PeccancyInformation peccancyInformation) {
        //如果不是总公司用户，或者模块管理员，则只查询自己录入的违章信息
        if(!hasHeadCompanyRole() && !hasPermission(ModuleManagerPermissionConstant.PECCANCY)){
            peccancyInformation.setInvoiceUserId(getCurrentUser().getUserId());
        }
        return new FebsResponse().success().data(peccancyInformationService.findPeccancyInformationList(peccancyInformation));
    }

    /**
     * 违章信息查询（分页）
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @GetMapping("peccancyInformation/list")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:view")
    public FebsResponse peccancyInformationList(QueryRequest request,
                                                @RequestParam(name = "startDate", required = true) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                                @RequestParam(name = "endDate", required = true) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
                                                @RequestParam(name = "projectName", required = false) String projectName,
                                                @RequestParam(name = "peccancyRealName", required = false) String peccancyRealName,
                                                @RequestParam(name = "status", required = true) String status,
                                                @RequestParam(name = "tenantId", required = true) String tenantId) {
        PeccancyInformationQueryDto peccancyInformation = new PeccancyInformationQueryDto();
        if (StringUtils.isNotBlank(projectName)) {
            peccancyInformation.setProjectName(projectName);
        }
        if (StringUtils.isNotBlank(peccancyRealName)) {
            peccancyInformation.setPeccancyRealName(peccancyRealName);
        }
        peccancyInformation.setStartDate(startDate);
        peccancyInformation.setEndDate(endDate);
        peccancyInformation.setTenantId(tenantId);
        peccancyInformation.setStatus(status);
        //如果不是总公司用户，或者模块管理员，则只查询自己录入的违章信息
        if(!hasHeadCompanyRole() && !hasPermission(ModuleManagerPermissionConstant.PECCANCY)){
            peccancyInformation.setInvoiceUserId(getCurrentUser().getUserId());
        }
        Map<String, Object> dataTable = getDataTable(this.peccancyInformationService.findPeccancyInformationDtoPage(request, peccancyInformation));
        return new FebsResponse().success().data(dataTable);
    }

    /**
     * 新增 违章信息
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @Log("新增违章信息")
    @PostMapping("peccancyInformation")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:add")
    public FebsResponse addPeccancyInformation(@RequestBody PeccancyInformationDto peccancyInformation) throws FebsException {
        try {
            checkInformationParams(peccancyInformation);
            peccancyInformation.setCreatedBy(getCurrentUser().getUserName());
            User user = getCurrentUser();
            peccancyInformation.setPeccancyNo(peccancyInformationService.createPeccancyNo(getCurrentUser().getTenantId(),getCurrentUser().getDeptId()));
            peccancyInformation.setInvoiceUserId(user.getUserId());
            peccancyInformation.setInvoiceRealName(user.getUname());
            peccancyInformation.setInvoiceDate(new Date());
            peccancyInformation.setDataSource(PeccancyConstant.DATA_SOURCE.PC);
            peccancyInformation.setPenaltyAmountStatus(PeccancyConstant.IS_OR_NO.NO);
            if(PeccancyConstant.INFORMATION_STATUS.WAITING_AUDIT.equals(peccancyInformation.getStatus())){
                //提交审核，校验是否自动神
                setAutoAuditAndIssuance(peccancyInformation);
            }

            this.peccancyInformationService.createPeccancyInformation(peccancyInformation);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "新增违章信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }



    /**
     * 逻辑删除 违章信息
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @Log("逻辑删除违章信息")
    @GetMapping("peccancyInformation/delete/{id}")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:delete")
    public FebsResponse deletePeccancyInformation(@PathVariable("id") String peccancyInformationIds) throws FebsException {
        try {
            PeccancyInformation queryData = peccancyInformationService.findPeccancyInformationById(peccancyInformationIds);
            if(ObjectUtils.isEmpty(queryData) || FebsConstant.INVALID.equals(queryData.getDeletedFlg())){
                return new FebsResponse().fail().message("该违章信息不存在或者已删除");
            }

            if(PeccancyConstant.IS_OR_NO.IS.equals(queryData.getPenaltyAmountStatus())){
                return new FebsResponse().fail().message("该违章信息已经缴纳过罚款，无法删除");
            }
            PeccancyInformation peccancyInformation = new PeccancyInformation();
            peccancyInformation.setDeletedBy(getCurrentUser().getUserName());
            peccancyInformation.setDeletedTime(new Date());
            peccancyInformation.setDeletedFlg(FebsConstant.INVALID);
            this.peccancyInformationService.deletePeccancyInformation(peccancyInformation, peccancyInformationIds);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "逻辑删除违章信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }


    /**
     * 修改 违章信息
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @Log("修改违章信息")
    @PostMapping("peccancyInformation/update")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:edit")
    public FebsResponse updatePeccancyInformation(@RequestBody PeccancyInformationDto peccancyInformation) throws FebsException {
        try {
            if(StringUtils.isBlank(peccancyInformation.getInformationId())){
                throw new FebsException("违章ID不能为空");
            }
            checkInformationParams(peccancyInformation);
            PeccancyInformation queryInformation = this.peccancyInformationService.findPeccancyInformationById(peccancyInformation.getInformationId());
            if(ObjectUtils.isEmpty(queryInformation)){
                return new FebsResponse().fail().message("未找到对应违章信息");
            }
            if(!PeccancyConstant.INFORMATION_STATUS.UPLOAD.equals(queryInformation.getStatus())
              && !PeccancyConstant.INFORMATION_STATUS.AUDIT_FAIL.equals(queryInformation.getStatus())){
                return new FebsResponse().fail().message("对应违章信息已被提交，请刷新后后再试");
            }

            if(PeccancyConstant.INFORMATION_STATUS.WAITING_AUDIT.equals(peccancyInformation.getStatus())){
                //提交审核，校验是否自动审核
                setAutoAuditAndIssuance(peccancyInformation);
            }
            peccancyInformation.setUpdatedBy(getCurrentUser().getUserName());
            this.peccancyInformationService.updatePeccancyInformationDto(peccancyInformation);
            return new FebsResponse().success();
        } catch (Exception e) {
            String message = "修改违章信息失败";
            log.error(message, e);
            String name = e.getClass().getName();
            if(FebsException.class.getName().equals(name)) {
                message = e.getMessage();
            }
            log.error(message, e);
            return failure(e,message);
        }
    }



    /**
     * 导出 PeccancyInformation的excel
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @PostMapping("peccancyInformation/excel")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:view")
    public void export(QueryRequest queryRequest, PeccancyInformationQueryDto peccancyInformation, HttpServletResponse response) throws FebsException {
        try {
            List<PeccancyInformation> peccancyInformations = this.peccancyInformationService.findPeccancyInformationPage(queryRequest, peccancyInformation).getRecords();
            ExcelKit.$Export(PeccancyInformation.class, response).downXlsx(peccancyInformations, false);
        } catch (Exception e) {
            String message = "导出Excel失败";
            log.error(message, e);
            throw new FebsException(message);
        }
    }

    /**
     * 统计用户当年违章信息
     *
     * @author wanghw
     * @date 2024-08-12 09:46:29
     */
    @Log("统计用户当年违章信息")
    @GetMapping("countPeccancy")
    @ResponseBody
    @RequiresPermissions("peccancyInformation:view")
    public FebsResponse countPeccancy(PeccancyInformationDto peccancyInformatio) throws FebsException {
        try {
            return new FebsResponse().success().data(this.peccancyInformationService.countPeccancyByUserId(peccancyInformatio));
        } catch (Exception e) {
            String message = "统计用户当年违章信息失败";
            log.error(message, e);
            return failure(e,message);
        }
    }


    /**
     * 校验新增编辑 违章信息请求参数
     *
     * @param peccancyInformation
     * @throws FebsException
     */
    private void checkInformationParams(PeccancyInformationDto peccancyInformation) throws FebsException {
        if (StringUtils.isBlank(peccancyInformation.getBusinessType())) {
            throw new FebsException("所属业务不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getTenantId())) {
            throw new FebsException("公司Id不能为空");
        }
//        if (StringUtils.isBlank(peccancyInformation.getPeccancyNo())) {
//            throw new FebsException("违章单号不能为空");
//        }
        if (StringUtils.isBlank(peccancyInformation.getProjectId())) {
            throw new FebsException("项目Id不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getProjectName())) {
            throw new FebsException("项目名称不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getClauseId())) {
            throw new FebsException("违章条款类型Id不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getClauseName())) {
            throw new FebsException("违章条款类型不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getClauseRuleId())) {
            throw new FebsException("违章条款规则Id不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getClauseRuleContent())) {
            throw new FebsException("违章条款内容不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getDisposeForm())) {
            throw new FebsException("处理形式不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getPeccancyType())) {
            throw new FebsException("违章类型不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getJobOperation())) {
            throw new FebsException("违章作业类别不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getPeccancyRootCause())) {
            throw new FebsException("违章原因不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getPeccancyAreaId())) {
            throw new FebsException("违章区域Id不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getPeccancyArea())) {
            throw new FebsException("违章区域不能为空");
        }
//        if (StringUtils.isBlank(peccancyInformation.getPeccancyAxis())) {
//            throw new FebsException("违章坐标不能为空");
//        }
        if (StringUtils.isBlank(peccancyInformation.getReason())) {
            throw new FebsException("惩罚原因不能为空");
        }
        if (StringUtils.isBlank(peccancyInformation.getPeccancyObject())) {
            throw new FebsException("违章对象不能为空");
        }

        if(PeccancyConstant.USE_SCOPE.DEPT.equals(peccancyInformation.getPeccancyObject())){
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserDeptId())) {
                throw new FebsException("违章部门Id不能为空");
            }

            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserDept())) {
                throw new FebsException("违章部门不能为空");
            }

        }else if(PeccancyConstant.USE_SCOPE.CONTRACTOR.equals(peccancyInformation.getPeccancyObject())){
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserContractorId())) {
                throw new FebsException("违章承包队所属承包商ID不能为空");
            }

            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserContractorName())) {
                throw new FebsException("违章承包队所属承包商不能为空");
            }
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserContractorTeamId())) {
                throw new FebsException("违章承包队Id不能为空");
            }
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserContractorTeamName())) {
                throw new FebsException("违章承包队不能为空");
            }

        }else {
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserId())) {
                throw new FebsException("违章人员Id不能为空");
            }

            if (StringUtils.isBlank(peccancyInformation.getPeccancyRealName())) {
                throw new FebsException("违章人员姓名不能为空");
            }
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserDeptId())) {
                throw new FebsException("违章人员部门Id不能为空");
            }
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserDept())) {
                throw new FebsException("违章人员部门不能为空");
            }
            if (StringUtils.isBlank(peccancyInformation.getPeccancyUserNo())) {
                throw new FebsException("违章人员工号不能为空");
            }
        }

    }



    /**
     * 判断是否自动审核或者自动签发
     * @param peccancyInformation
     */
    private void setAutoAuditAndIssuance(PeccancyInformationDto peccancyInformation){
        PeccancyModuleConfig moduleConfig = moduleConfigService.findPeccancyModuleConfigByTenantId(getCurrentTenantId());
        if(ObjectUtils.isNotEmpty(moduleConfig)){
            //有模块化配置
            if(PeccancyConstant.IS_OR_NO.IS.equals(moduleConfig.getReviewSwitch())){
                //开启审核开关
                if(PeccancyConstant.CONFIG_TYPE.AUTO.equals(moduleConfig.getReviewType())){
                    //自动审核流程
                    log.info("有模块配置，审核开关打开，已配置自动审核");

                }else {
                    //手动审核流程
                    log.info("有模块配置，审核开关打开，已配置手动审核");
                }
            }else {
                //关闭审核开关
                if(PeccancyConstant.IS_OR_NO.IS.equals(moduleConfig.getIssuedSwitch())){
                    //审核开关关闭  ， 签发开关开启
                    if(PeccancyConstant.CONFIG_TYPE.AUTO.equals(moduleConfig.getIssuedType())){
                        log.info("有模块配置，审核开关关闭，签发开关打开，已配置自动签发");
                        //自动签发流程

                    }else {
                        //手动签发流程
                        log.info("有模块配置，审核开关关闭，签发开关打开，已配置手动签发");
                        setAutoAudit(peccancyInformation);
                    }
                }else {
                    log.info("有模块配置，审核开关关闭，签发开关关闭，直接自动签发");
                    setAutoIssuance(peccancyInformation);
                }

            }


        }else{
            log.info("未进行模块配置，默认直接签发");
            //没有模块审核签发配置  直接签发
            setAutoIssuance(peccancyInformation);
        }


    }


    /**
     * 自动审核状态
     * @param peccancyInformation
     */
    private void setAutoAudit(PeccancyInformationDto peccancyInformation){
        peccancyInformation.setStatus(PeccancyConstant.INFORMATION_STATUS.WAITING_ISSUANCE);
        peccancyInformation.setAuditDate(new Date());
        peccancyInformation.setAuditRemark("系统自动审核");
        peccancyInformation.setAuditRealName("系统");
    }

    /**
     * 自动签发状态
     * @param peccancyInformation
     */
    private void setAutoIssuance(PeccancyInformationDto peccancyInformation){
        peccancyInformation.setStatus(PeccancyConstant.INFORMATION_STATUS.ISSUANCED);

        peccancyInformation.setAuditDate(new Date());
        peccancyInformation.setAuditRemark("系统自动审核");
        peccancyInformation.setAuditRealName("系统");


        peccancyInformation.setIssuanceDate(new Date());
        peccancyInformation.setIssuanceRemark("系统自动签发");
        peccancyInformation.setIssuanceRealName("系统");
    }

}
